package cn.yunyichina.provider.hisiface.service;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.yunyichina.provider.hisiface.util.Constants;
import cn.yunyichina.provider.hisiface.util.HttpUtils;
import cn.yunyichina.provider.hisiface.util.PostFailureException;
import cn.yunyichina.provider.hisiface.util.ServiceRouter;
import cn.yunyichina.provider.iface.entity.base.OrgSettingVoResponse;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.hisiface.BaseVo;
import cn.yunyichina.provider.iface.entity.hisiface.register.OrderRegisterVoResponse;
import cn.yunyichina.utils.convert.JsonUtils;

import com.alibaba.fastjson.JSON;

/**
 * 通用服务接口抽象类
 * 
 * @author zhou
 *
 */
public abstract class AbstractService {

	 private Logger logger = LoggerFactory.getLogger(AbstractService.class);
	
	/**
	 * 简单执行
	 * 
	 * @param methodCode
	 * @param methodName
	 * @param baseVo
	 * @param voResponse
	 * @return
	 */
	protected <T> ResCommon<T> doExec(String methodCode, String methodName, BaseVo baseVo, Class<T> voResponse) {
		ResCommon<T> resCommon = new ResCommon<>(ResCommon.SUCCESS_CODE, methodName + "成功");
		String data = JsonUtils.toJsonString(baseVo);
		
		logger.info(methodName + "开始 " + "methodCode: " + methodCode + ", data: " + data);
		
		OrgSettingVoResponse orgSetting = ServiceRouter.getFrontInfo(baseVo.getSessionId(), baseVo.getHospitalCode(), baseVo.getBranchCode(), methodCode);
		if (! ServiceRouter.checkRouterMap(orgSetting)) {
			resCommon.setResultCodeAndMessage(Constants.ResultCode.FAILURE_CODE, "查询前置机服务地址失败，url为空或者signKey为空");
			logger.info(methodName + "结束，查询前置机服务信息失败 response: [resultCode: " + resCommon.getResultCode()
					+ ", resultMessage: " + resCommon.getResultMessage()  + "]");
			
			return resCommon;
		}
		
		String url = orgSetting.getUrl();
		String signKey = orgSetting.getSignKey();
        
		logger.info("请求前置机 frontUrl: " + url + ", methodCode: " + methodCode + ", data: " + data);
        
        // 调用前置机
		try {
			String responseStr = HttpUtils.doSslPost(url, signKey, baseVo.getSessionId(), methodCode, data);
			
			logger.info("前置机返回 methodCode: " + methodCode + ", frontResponse: " + responseStr);
			
			Response frontResponse = JsonUtils.parseObject(responseStr, Response.class);
			String resultCode = frontResponse.getResultCode();
	        if (Constants.HisResultCode.SUCCESS_CODE.equals(resultCode)) {
	        	if (voResponse != null) {
	        		T t = JsonUtils.parseObject(frontResponse.getResult(), voResponse);
	        		resCommon.setResult(t);
	        	}
	        } else {
				resCommon
						.setResultCodeAndMessage(
								Constants.HisResultCode.FAILURE_CODE
										.equals(resultCode) ? Constants.ResultCode.FAILURE_CODE
										: Constants.ResultCode.EXCEPTION_CODE,
								frontResponse.getResultMessage());
	        }
		} catch (Exception e) {
			if (e instanceof PostFailureException) {
				// 发送http请求给前置机时发生异常，失败
				resCommon.setResultCodeAndMessage(Constants.ResultCode.FAILURE_CODE, "请求前置机失败。" + e.getMessage());
				logger.error("请求前置机失败", e);
			} else {
				// 处理前置机的response时发生异常
				resCommon.setResultCodeAndMessage(Constants.ResultCode.EXCEPTION_CODE, "处理前置机Response异常。" + e.getMessage());
				logger.error("处理前置机Response异常", e);
			}
		}
        
		logger.info(methodName + "结束 response: " + JSON.toJSONString(resCommon));
		
		return resCommon;
	}
	
	/**
	 * 简单执行，返回集合类型结果
	 * 
	 * @param methodCode
	 * @param methodName
	 * @param baseVo
	 * @param voResponse
	 * @return
	 */
	protected <T> ResCommon<List<T>> doExecList(String methodCode, String methodName, BaseVo baseVo, Class<T> voResponse) {
		ResCommon<List<T>> resCommon = new ResCommon<>(ResCommon.SUCCESS_CODE, methodName + "成功");
		String data = JsonUtils.toJsonString(baseVo);
		
		logger.info(methodName + "开始 " + "methodCode: " + methodCode + ", data: " + data);
		
		OrgSettingVoResponse orgSetting = ServiceRouter.getFrontInfo(baseVo.getSessionId(), baseVo.getHospitalCode(), baseVo.getBranchCode(), methodCode);
		if (! ServiceRouter.checkRouterMap(orgSetting)) {
			resCommon.setResultCodeAndMessage(Constants.ResultCode.FAILURE_CODE, "查询前置机服务地址失败，url为空或者signKey为空");
			logger.info(methodName + "结束，查询前置机服务信息失败 response: [resultCode: " + resCommon.getResultCode()
					+ ", resultMessage: " + resCommon.getResultMessage()  + "]");
			
			return resCommon;
		}
		
		String url = orgSetting.getUrl();
		String signKey = orgSetting.getSignKey();
        
		logger.info("请求前置机 frontUrl: " + url + ", methodCode: " + methodCode + ", data: " + data);
        
        // 调用前置机
		try {
			String responseStr = HttpUtils.doSslPost(url, signKey, baseVo.getSessionId(), methodCode, data);
			
			logger.info("前置机返回 methodCode: " + methodCode + ", frontResponse: " + responseStr);

			Response frontResponse = JsonUtils.parseObject(responseStr, Response.class);
			String resultCode = frontResponse.getResultCode();
	        if (Constants.HisResultCode.SUCCESS_CODE.equals(resultCode)) {
        		List<T> list = JsonUtils.parseArray(frontResponse.getResult(), voResponse);
        		resCommon.setResult(list);
	        } else {
	        	resCommon
				.setResultCodeAndMessage(
						Constants.HisResultCode.FAILURE_CODE
								.equals(resultCode) ? Constants.ResultCode.FAILURE_CODE
								: Constants.ResultCode.EXCEPTION_CODE,
						frontResponse.getResultMessage());
	        }
		} catch (Exception e) {
			if (e instanceof PostFailureException) {
				// 发送http请求给前置机时发生异常，失败
				resCommon.setResultCodeAndMessage(Constants.ResultCode.FAILURE_CODE, "请求前置机失败。" + e.getMessage());
				logger.error("请求前置机失败", e);
			} else {
				// 处理前置机的response时发生异常
				resCommon.setResultCodeAndMessage(Constants.ResultCode.EXCEPTION_CODE, "处理前置机Response异常。" + e.getMessage());
				logger.error("处理前置机Response异常", e);
			}
		}
        
		logger.info(methodName + "结束 response: " + JSON.toJSONString(resCommon));
		
		return resCommon;
	}

	public static void main(String []a){
		String responseStr = "{\"result_code\":\"0\",\"result_message\":\"成功\",\"result\":\"{\\\"extend_params\\\":\\\"{\\\"cancel_bill_no\\\":\\\"13057062\\\",\\\"cancel_serial_no\\\":\\\"13057062\\\",\\\"czybm\\\":\\\"\\\",\\\"desc\\\":\\\"\\\",\\\"reg_fee\\\":\\\"\\\",\\\"treat_fee\\\":\\\"\\\",\\\"yljgbm\\\":\\\"\\\"}\\\",\\\"his_ord_num\\\":\\\"13057061\\\"}\"}";
		Response frontResponse = JsonUtils.parseObject(responseStr, Response.class);
		OrderRegisterVoResponse list = JsonUtils.parseObject(frontResponse.getResult(), OrderRegisterVoResponse.class);
		System.out.println(list );
	}
}
